import time,json,hmac,urllib,base64,requests
from urllib.parse import parse_qs,urlencode
from flask import Blueprint
from flask_restful import Api,Resource,reqparse
from common.utlis.my_output_json import custom_output_json
from models.users import *
from werkzeug.security import check_password_hash
from models import db

from common.utlis.jwt_util import _generate_token


oauth_user_bp = Blueprint('oauth_user', __name__, url_prefix='/oauth')

# 创建蓝图的主入口
api = Api(oauth_user_bp)

# 统一后端返回给前端的数据结构
@api.representation('application/json')
def output_json(data, code,headers=None):
    resp = custom_output_json(data, code)
    return resp

class DingDingResource(Resource):

    def get_dingding_user(self, code):
        """获取扫码登录的信息"""
        # 构建三个参数的值
        appid = 'dingoajf8cqgyemqarekhr'
        appSecret = 'Fcah25vIw-koApCVN0mGonFwT2nSze14cEe6Fre8i269LqMNvrAdku4HRI2Mu9VK'
        timestamp = str(int(time.time()*1000))
        # .digest()获取hash对象的值
        signature = base64.b64encode(
            hmac.new(appSecret.encode('utf-8'),timestamp.encode('utf-8'),digestmod='sha256').digest())
        base_url = "https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature="
        # 拼接url
        url = base_url + urllib.parse.quote(signature.decode('utf-8')) + "&timestamp=" + timestamp + "&accessKey=" + appid
        data = json.dumps({'tmp_auth_code':code})
        try:
            resp = requests.post(url, data, headers={'Content-Type': 'application/json'})
            print("resp>>>", resp.json())
            user_info = resp.json()
            if user_info['errcode'] != 0:
                # 获取当前登录的而用户信息失败
                return {'code': 500, "message": '根据code获取钉钉用户信息失败'}
            # 把用户信息转换成dict
            user_info_dict = user_info['user_info']
            return user_info_dict
        except Exception as e:
            # 根据code 获取用户信息失败
            return {'code': 500, "message": 'post 获取钉钉用户信息失败'}

    def get(self):
        """
        1.获取code值
        2. 构建accessKey(应用的AppKey)
         timestamp，(当前的时间戳，是单位毫秒)
         signature:(appSecret计算出来的签名值)
         三个参数的值
        3. 发起请求：
        post https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey=ACCESS_KEY&timestamp=TIMESTAMP&signature=SIGNATURE
        :return: userInfo
        """
        parser = reqparse.RequestParser()
        parser.add_argument('code')
        args = parser.parse_args()
        # 1.获取code值
        code = args.get('code')
        # 发起请求,获取当前登录的用户信息
        user_info = self.get_dingding_user(code)
        # 根据钉钉的用户信息获取钉钉的openid
        openid = user_info['openid']
        print('哦》》',openid)
        if openid:
            # 获取openid成功，从oauth_user表查看当前钉钉用户是否和网站的用户绑定过
            oauth_user = OAuthUserModel.query.filter_by(oauth_id=openid).first()
            # 存在，说明绑定过
            if oauth_user:
                # 获取绑定的用户信息
                user = User.query.filter_by(id=oauth_user.user).first()
                # 添加token
                data = {
                    'id':user.id,
                    'user':user.username
                }
                token = _generate_token(data,is_refresh=False)
                return {'code':200,'account':user.username, 'id':user.id,'token':token}
            # 不存在没绑定
            else:
                return {'message':'没有绑定用户,请先绑定', 'id':openid}

# 绑定钉钉的视图
class DingdingBindUser(Resource):

    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument('account')
        parser.add_argument('password')
        parser.add_argument('unid')
        args = parser.parse_args()
        account = args.get('account')
        password = args.get('password')
        unid = args.get('unid')

        user = User.query.filter_by(username=account).first()
        if not user:
            return {'message':'用户未注册请先注册', 'code':400}
        else:
            pwd = check_password_hash(user.password,password)
            if not pwd:
                return {"message":'密码错误', 'code':400}
            else:
                oauth = OAuthUserModel(oauth_id = unid,user=user.id,oauth_type='dingding')
                db.session.add(oauth)
                db.session.commit()
                data = {
                    'id': user.id,
                    'name': user.username
                }
                token = _generate_token(data,is_refresh=False)

                data_ = {
                    'account': user.username,
                    'token': token,
                    'id': user.id
                }
                return {'message':'绑定成功', 'code':200, 'data':data_}

# 获取微博用户信息的视图
class WeiboResource(Resource):
    def get_weibo_user(self, code):
        data_ = {
            "client_id": "2775107052",
            "client_secret": "718b38b04fc387700cc1595b30875b19",
            "grant_type": "authorization_code",
            "redirect_uri": "http://127.0.0.1:8080/weibo",
            "code": code,
        }
        base_url = "https://api.weibo.com/oauth2/access_token"
        try:
            resp = requests.post(url=base_url, data=data_).json()
            print("=======>resp", resp)
        except Exception as e:
            return {"message": "获取微博用户信息失败", "code": 400}

        if not resp["access_token"]:
            return {"message": "根据code获取用户信息失败", "code": 400}
        else:
            print('resp',resp)
            return resp
    def get(self):
        """根据code 获取微博用户信息"""
        parser = reqparse.RequestParser()
        parser.add_argument('code')
        args = parser.parse_args()
        # 1.获取code值
        code = args.get('code')
        print('code',code)
        user_dict = self.get_weibo_user(code)
        uid = user_dict['uid']
        oauth_user = OAuthUserModel.query.filter_by(oauth_id = uid, oauth_type='weibo').first()
        print('信息>>',oauth_user)
        if oauth_user:
            user = User.query.filter_by(id=oauth_user.user).first()
            payload = {'id': user.id}
            token = _generate_token(payload)
            return {'message':'登陆成功', 'code':200, 'token':token}
        else:
            return {'message':'用户未绑定', 'code':400}


# 绑定微博的视图
class WeiboBindUser(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("account")
        parser.add_argument("password")
        parser.add_argument("unid")
        args = parser.parse_args()
        account = args["account"]
        password = args["password"]
        unid = args["unid"]

        user = User.query.filter_by(username=account).first()
        if not user:
            return {"message": "用户未注册，请先注册", "code": 400}

        else:
            if not check_password_hash(user.password, password):
                return {"message": "密码错误", "code": 400}

            else:
                oauth_user = OAuthUserModel(oauth_id=unid, user=user.id, oauth_type="weibo")
                db.session.add(oauth_user)
                db.session.commit()
                payload = {"uid": user.id}
                token = _generate_token(payload)
                data_ = {
                    "id": user.id,
                    "account": user.username,
                    "token": token,
                }
                return {"message": "绑定成功", "code": 200, "data": data_}






api.add_resource(DingDingResource, '/dingding')
api.add_resource(DingdingBindUser, '/dingding/bind')

api.add_resource(WeiboResource, '/weibo')
api.add_resource(WeiboBindUser, '/weibo/bind')






































































































